package code.example.base.collection.queue.blockingqueue;

import code.example.base.collection.queue.Person;
import code.example.base.collection.queue.TestPriorityQueue;
import code.example.tool.LogFactory;

import java.text.SimpleDateFormat;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.DelayQueue;

/**
 *  DelayQueue  一个延迟队列，无界队列，实现了 BlockingQueue。
 *   --元素指定时间到达，才能从队列中取出。
 *
 *   offer put add  -- 都可成功(原因是无界对列)，不阻塞（对于put），不异常（对于add）,不返回false(对于offer)
 *   remove() --如时间没有到达或空队列，throw NoSuchElementException
 *   poll()--如时间没有到达或空队列， return null
 *   take()--阻塞，直至有元素可以取出，（等待时间到达或新元素加入）
 *
 *   元素需要实现Delay 接口：
 *      方法：getDelay 返回 0 或负数，表示时间到达。
 *            compareTo 用于按时间排序。
 *   内部使用PriorityQueue +     compareTo 方法实现按顺序取出元素（基于二叉树算法）。
 *
 *    线程安全：使用的ReentrantLock ,方法内部加锁。
 *
 */
public class TestDelayQueue {

    public void test() throws InterruptedException{
        BlockingQueue<TimerGift> queue =new DelayQueue<TimerGift>();
        long time = System.currentTimeMillis() ;
        TimerGift timerGift = new TimerGift(new Date(time+1000),"iphone1");//1秒之后开启
        queue.offer(timerGift);
        timerGift = new TimerGift(new Date(time+2000),"iphone2");//2秒之后开启
        queue.offer(timerGift);
        timerGift = new TimerGift(new Date(time+3000),"iphone3");//3秒之后开启
        queue.offer(timerGift);
        timerGift = new TimerGift(new Date(time+4000),"iphone4");//4秒之后开启
        queue.offer(timerGift);
        timerGift = new TimerGift(new Date(time+5000),"iphone5");//5秒之后开启
        queue.offer(timerGift);

        int count = queue.size();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

        for(int i=0;i<count;i++){
            TimerGift gift = queue.take();

            LogFactory.getLog().info("sys-time:"+sdf.format(new Date())+" ,gift-time:"+sdf.format(gift.getDate())+",gift:"+gift.getGift());
        }
    }


    public static void main(String [] args){
        try {
            new TestDelayQueue().test();
        }catch (Exception e){
            LogFactory.getLog().error(e);
        }
    }
}
